package symbolTable;

import java.util.ArrayList;
import syntaxtree.*;
public class SymbolTable {
	public ArrayList<StoreClass> classList = new ArrayList<StoreClass>();
	
	public void addClass(String className, String extendClass){
		StoreClass c = new StoreClass();
		c.name = className;
		c.extendClass = extendClass;
		classList.add(c);
	}
	
	public StoreClass findClass(String name){
		for(int i=0; i<classList.size(); i++) //encontra a posicao
			if(classList.get(i).name == name)
				return classList.get(i);
		return null;
	}
	
	public Type findMethodFormalType(String className, String methodName, String paramName){
		StoreClass c = findClass(className);
		if (c == null)
			return null; //acontece qd recursao vai para a classe pai
		StoreMethod m = c.findMethod(methodName);
		if(m != null){ //se achou metodo
			StoreVariable att = m.findFormal(paramName);
			if(att != null) //se achou parametro
				return att.type;
		} //se nao achou nenhum, busca na classe pai
		return this.findMethodFormalType(c.extendClass, methodName, paramName);
	}
	
	public String findMethodFormalNameByPos(String className, String methodName, int pos){
		StoreClass c = findClass(className);
		if (c == null)
			return null; //acontece qd recursao vai para a classe pai
		StoreMethod m = c.findMethod(methodName);
		if(m != null){ //se achou metodo
			StoreVariable att = m.findFormalByPos(pos);
			if(att != null) //se achou parametro
				return att.name;
		} //se nao achou nenhum, busca na classe pai
		return this.findMethodFormalNameByPos(c.extendClass, methodName, pos);
	}
	
	public Type findMethodFormalTypeByPos(String className, String methodName, int pos){
		StoreClass c = findClass(className);
		if (c == null)
			return null; //acontece qd recursao vai para a classe pai
		StoreMethod m = c.findMethod(methodName);
		if(m != null){ //se achou metodo
			StoreVariable att = m.findFormalByPos(pos);
			if(att != null) //se achou parametro
				return att.type;
		} //se nao achou nenhum, busca na classe pai
		return this.findMethodFormalTypeByPos(c.extendClass, methodName, pos);
	}
	
	public Type findMethodLocalType(String className, String methodName, String paramName){
		StoreClass c = findClass(className);
		if (c == null)
			return null; //acontece qd recursao vai para a classe pai
		StoreMethod m = c.findMethod(methodName);
		if(m != null){ //se achou metodo
			StoreVariable att = m.findLocal(paramName);
			if(att != null) //se achou parametro
				return att.type;
		} //se nao achou, busca na classe pai
		return this.findMethodLocalType(c.extendClass, methodName, paramName);
	}
	
	public Type findMethodReturnType(String className, String methodName){
		StoreClass c = findClass(className);
		if(c == null)
			return null; //acontece qd recursao vai para a classe pai
		StoreMethod m = c.findMethod(methodName);
		if(m != null) //se achou metodo
			return m.returnType;
		else //se nao achou metodo, busca na classe pai
			return this.findMethodReturnType(c.extendClass, methodName);
	}
	
	public Type findClassAttributeType(String className, String attName){
		StoreClass c = findClass(className);
		if(c == null)
			return null; //acontece qd recursao vai para a classe pai
		StoreVariable att = c.findVariable(attName);
		if(att != null) //se achou atributo
			return att.type;
		else //se nao achou atributo, busca na classe pai
			return this.findClassAttributeType(c.extendClass, attName);
	}
}
